<?php

$wgExtensionFunctions[] = "wfDataAggregator";
 
// Extension credits that will show up on Special:Version    
$wgExtensionCredits['other'][] = array(
    'path'         => __FILE__,
        'name'         => 'Data Aggregator',
        'version'      => '0.31',
        'author'       => 'Weiming Li', 
        'url'          => 'http://www.mediawiki.org/wiki/Extension:DataAggregator',
        'description'  => 'This extension enables you to aggregate the data automatically from different pages which are conformed to one or multiple wiki templates.'
);
 
function wfDataAggregator()
{
        global $wgParser;
        $wgParser->setHook("da", "renderTable");
}
 
/**
* This function renders the table.
* $input = text between <da> and </da>
* $argv = key/val array of options in the <da> tag.
*/
function renderTable($input, $argv)
{
        global $wgScript;
        // Check the template is given or not.
	if(!isset($argv["template"])) 
	{
		return "Error: No template given.  Please use the format <tt>&lt;da template='Name Of Template'&gt;...&lt;/da&gt;</tt>";
	}else
	{
		$templates = explode("|", $argv["template"]);
		//If we have multiple wiki templates specified
		if(count($templates) > 1)
		{
			foreach ($templates as $key=>$value)
			{	
				$temp_sql = $temp_sql."tl_title='".trim($value)."' or ";
				$temp_reg = trim($value)." |".$temp_reg;
			}
			$temp_sql = substr($temp_sql, 0, -3);	
			$temp_reg = str_replace("_"," ",substr($temp_reg, 0, -1));	//take out spare pipeline
 
			$reg_exp = '/{{ *('.$temp_reg.').[^{{]*}}/';
		}else
		//Only one template is specifieid
		{
			$temp_reg = str_replace("_"," ",$argv["template"]);
			$temp_sql = "tl_title='".trim($argv["template"])."'";
			$reg_exp = '/{{ *'.$temp_reg.'.[^{{]*}}/';
		}
	}
        // Header type.  If "rowtitle" is given, use that.
        // Otherwise, use dynamic row title (every variable used in the template)
        $dynhead = true;
        $rowtitles = array();
        if(isset($argv["rowtitles"]))
        {
                $rowtitles = explode("|", $argv["rowtitles"]);
                $dynhead = false;
        }
 
        // Preset output to the input (stuff between <da> and </da>
        $output = $input;
 
        global $wgDBprefix, $wgContLang;
        //$namespaceNames = $wgContLang->namespaceNames; // this produces an error, since namespaceNames is a protected attribute
        $namespaceNames = $wgContLang->getNamespaces();
        $data = array();
 
        // If category is set, then query against the db to get pages belong to the specified category
        if (isset($argv["category"]))
        {
                $query = "select * from ".$wgDBprefix."templatelinks left join ".$wgDBprefix."page on ".$wgDBprefix."templatelinks.tl_from=".$wgDBprefix."page.page_id where (".$temp_sql.") and page.page_id  in (select cl_from from categorylinks where cl_to ='".mysql_real_escape_string($argv["category"])."') order by page_title";
        }else
        {
                $query = "select * from ".$wgDBprefix."templatelinks left join ".$wgDBprefix."page on ".$wgDBprefix."templatelinks.tl_from=".$wgDBprefix."page.page_id where (".$temp_sql.") order by page_title";
        }
 
		//Execute the SQL query
        $result = mysql_query($query)
        or die("Query failed: ".mysql_error()." Actual query: ".$query);
 
		while($row = mysql_fetch_object($result))
        {
                $q2 = "select rev_text_id from ".$wgDBprefix."revision where rev_page=".$row->page_id." order by rev_timestamp desc limit 1";
 
                if(($res2 = mysql_query($q2)) && ($row2 = mysql_fetch_object($res2)))
                {
                        $q3 = "select * from ".$wgDBprefix."text where old_id=".$row2->rev_text_id;
                        if(($res3 = mysql_query($q3)) && ($row3 = mysql_fetch_object($res3)))
                        {
                         	$row3->old_text = str_replace("\n", " ", $row3->old_text);    # turn the article into one long line

				preg_match_all ('/{{.[^{{]*}}/', $row3->old_text, $n );
				//If the page only have one wiki template reference
				if(count($n[0])==1)
				{
					$matches = $n;
				}else	//Multiple templates reference in one page
				{
					preg_match_all ( $reg_exp, $row3->old_text, $matches );
				}
 
				//Start to parse detailed content from a transclusion section quoted by {{Template Name....}}
				foreach ($matches[0] as $key=>$value){
 
	                                // create an array from of the template fields
        	                        $kvs = explode( "|", substr($value, 2, -2));
                	                // remove first field: template name
                        	        unset( $kvs[0] );
 
                                	foreach($kvs as $kv)
                                	{
                                        	$kv = trim($kv);
	                                        if($kv == "") continue;
        	                                $eq = strpos($kv, "=");
                	                        if($eq === false) continue;
                        	                $key = trim(substr($kv, 0, $eq));
                                	        $val = trim(substr($kv, $eq+1));
                                       		$item[$key] = $val;
	                                        if($dynhead && !in_array($key, $rowtitles)) array_push($rowtitles, $key);
        	                        }
                	                if(sizeof($item) > 0) {
                        	                $title = str_replace("_", " ", $row->page_title);
                                	        if ( $row->page_namespace != NS_MAIN ) {
                                        	        $title = $namespaceNames[$row->page_namespace].":".$title;
						}
                                        	$data[$title] = $item;
                                        }
				}		
			}
                }
        }
 
 
        // Skip this if there's no data to display.
        // Otherwise, it will create the table
        if(sizeof($data) > 0)
        {
                $output.= "<table";
 
                // Read the table style parameters
                foreach($argv as $key=>$val)
                {
                        if($key == "template" || $key == "rowtitles" || $key == "category" || $key == "fcc") continue;
                        $output.= " $key=\"$val\"";
                }
                $output.= ">\n";
                $output.= "<tr bgcolor=#cccccc><th>&nbsp;</th>\n";
 
                foreach($data as $page=>$item)
                {
                        $link = $page;
                        // page name as link title
                        $colon = strpos($link, ":");                         
                        if ( $colon >= 0 ) $link = substr($link, $colon);     # without leading Category:/Wiki:/Special: statements

                        // Changing this line will change the text that appears as the article link:
                        // $link = "article";
 
                        // Compose the table headers, the header cells style can be modified right here
                        $output.= "<th bgcolor=#cccccc><a href='".$wgScript."?title=".urlencode($page)."'>$link</a></th>\n";
                }
                $output.= "</tr>\n";
 
                // Table rows
                foreach($rowtitles as $rowtitle)
                {
                        // Composing the row title
                        $output.="<td bgcolor=#cccccc><b>".$rowtitle."</b></td>\n";
 
                        // Tabel content cells
                        foreach($data as $page=>$item)
                        {
                                if(isset($item[$rowtitle]))
                                        $output.= "<td align='center'>".$item[$rowtitle]."</td>\n";
                                else
                                        $output.= "<td>&nbsp;</td>\n";
 
                        }
 
                // Finishing of one row
                $output.= "</tr>\n";
                }
 
                $output.= "</table>\n";
        }
        else
        {
                // No data found
                $output.= "Template ".$argv["template"]." has no data. Please double check your template name spelling.";
        }
 
        return $output;
}

ini_set('error_reporting', E_ALL|E_STRICT);
ini_set('display_errors', 1);
?>